import { useEffect, useState, useRef } from 'react'
import { Modal, Button, Space, Badge, Empty, Spin } from '@arco-design/web-react'
import { IconRefresh, IconDownload } from '@arco-design/web-react/icon'
import { getTaskLogs } from '@/api/task'
import { signalRService, HubEvent, type TaskLogData } from '@/utils/websocket'
import type { TaskLog } from '@/types'
import dayjs from 'dayjs'
import './index.css'

interface LogViewerModalProps {
  visible: boolean
  taskId: number | null
  taskName?: string
  onCancel: () => void
}

const levelConfig: Record<
  string,
  { color: string; bgColor: string; status: any }
> = {
  info: { color: '#165dff', bgColor: '#e8f3ff', status: 'processing' },
  warning: { color: '#ff7d00', bgColor: '#fff7e8', status: 'warning' },
  error: { color: '#f53f3f', bgColor: '#ffece8', status: 'error' },
  debug: { color: '#86909c', bgColor: '#f7f8fa', status: 'default' },
}

export default function LogViewerModal({
  visible,
  taskId,
  taskName,
  onCancel,
}: LogViewerModalProps) {
  const [logs, setLogs] = useState<TaskLog[]>([])
  const [loading, setLoading] = useState(false)
  const [autoRefresh, setAutoRefresh] = useState(true)
  const [isRealtimeConnected, setIsRealtimeConnected] = useState(false)
  const logContainerRef = useRef<HTMLDivElement>(null)
  const shouldScrollRef = useRef(true)

  // 加载日志
  const loadLogs = async () => {
    if (!taskId) return
    setLoading(true)
    try {
      const data = await getTaskLogs(taskId)
      setLogs(data)
      // 如果用户没有手动滚动，自动滚动到底部
      if (shouldScrollRef.current && logContainerRef.current) {
        setTimeout(() => {
          if (logContainerRef.current) {
            logContainerRef.current.scrollTop = logContainerRef.current.scrollHeight
          }
        }, 100)
      }
    } catch (error) {
      console.error('Failed to load logs:', error)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    if (visible && taskId) {
      loadLogs()

      // 尝试建立 SignalR 连接并订阅实时日志
      const connectSignalR = async () => {
        try {
          if (!signalRService.isConnected()) {
            await signalRService.connect()
          }
          await signalRService.subscribeTaskLogs(taskId)
          setIsRealtimeConnected(true)
        } catch (error) {
          console.warn('Failed to connect SignalR, falling back to polling:', error)
          setIsRealtimeConnected(false)
        }
      }

      connectSignalR()

      // SignalR 实时日志回调
      const handleRealtimeLog = (data: TaskLogData) => {
        if (data.taskId === taskId) {
          const logLevel = data.logLevel.toLowerCase() as 'info' | 'warning' | 'error' | 'debug'
          const newLog: TaskLog = {
            taskId: data.taskId,
            timestamp: data.timestamp,
            level: logLevel,
            message: data.logContent,
          }
          setLogs((prev) => [...prev, newLog])
          // 自动滚动到底部
          if (shouldScrollRef.current && logContainerRef.current) {
            setTimeout(() => {
              if (logContainerRef.current) {
                logContainerRef.current.scrollTop = logContainerRef.current.scrollHeight
              }
            }, 100)
          }
        }
      }

      signalRService.on(HubEvent.RECEIVE_TASK_LOG, handleRealtimeLog)

      // 启用自动刷新时,使用轮询作为备选方案
      let timer: ReturnType<typeof setInterval> | undefined
      if (autoRefresh) {
        timer = setInterval(loadLogs, 3000)
      }

      return () => {
        if (timer) clearInterval(timer)
        signalRService.off(HubEvent.RECEIVE_TASK_LOG, handleRealtimeLog)
        if (taskId) {
          signalRService.unsubscribeTaskLogs(taskId).catch(console.error)
        }
      }
    }
  }, [visible, taskId, autoRefresh])

  // 监听滚动事件，判断用户是否手动滚动
  const handleScroll = () => {
    if (logContainerRef.current) {
      const { scrollTop, scrollHeight, clientHeight } = logContainerRef.current
      // 如果滚动到底部附近（20px误差），则自动滚动
      shouldScrollRef.current = scrollHeight - scrollTop - clientHeight < 20
    }
  }

  // 下载日志
  const handleDownload = () => {
    const content = logs
      .map(
        (log) =>
          `[${dayjs(log.timestamp).format('YYYY-MM-DD HH:mm:ss')}] [${log.level.toUpperCase()}] ${log.message}`
      )
      .join('\n')

    const blob = new Blob([content], { type: 'text/plain' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `task-${taskId}-logs-${dayjs().format('YYYYMMDDHHmmss')}.txt`
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
    URL.revokeObjectURL(url)
  }

  // 重置滚动状态
  useEffect(() => {
    if (visible) {
      shouldScrollRef.current = true
    }
  }, [visible])

  return (
    <Modal
      title={
        <Space>
          <span>任务日志</span>
          {taskName && <span style={{ color: '#86909c' }}>- {taskName}</span>}
        </Space>
      }
      visible={visible}
      onCancel={onCancel}
      footer={null}
      style={{ width: '80vw', maxWidth: 1200 }}
      autoFocus={false}
    >
      <div className="log-viewer-toolbar">
        <Space>
          <Button
            type="primary"
            size="small"
            icon={<IconRefresh />}
            onClick={loadLogs}
            loading={loading}
          >
            刷新
          </Button>
          <Button
            size="small"
            type={autoRefresh ? 'primary' : 'default'}
            onClick={() => setAutoRefresh(!autoRefresh)}
          >
            {autoRefresh ? '停止自动刷新' : '启用自动刷新'}
          </Button>
          <Button
            size="small"
            icon={<IconDownload />}
            onClick={handleDownload}
            disabled={logs.length === 0}
          >
            下载日志
          </Button>
        </Space>
        <Space>
          <span style={{ fontSize: 12, color: '#86909c' }}>
            共 {logs.length} 条日志
          </span>
          {isRealtimeConnected ? (
            <Badge status="success" text="实时连接" />
          ) : autoRefresh ? (
            <Badge status="processing" text="轮询刷新中" />
          ) : null}
        </Space>
      </div>

      <div
        ref={logContainerRef}
        className="log-viewer-container"
        onScroll={handleScroll}
      >
        {loading && logs.length === 0 ? (
          <div className="log-viewer-loading">
            <Spin />
          </div>
        ) : logs.length === 0 ? (
          <Empty description="暂无日志数据" />
        ) : (
          <div className="log-viewer-content">
            {logs.map((log, index) => {
              const config = levelConfig[log.level] || levelConfig.debug
              return (
                <div key={index} className="log-line">
                  <span className="log-timestamp">
                    {dayjs(log.timestamp).format('YYYY-MM-DD HH:mm:ss.SSS')}
                  </span>
                  <span
                    className="log-level"
                    style={{
                      color: config.color,
                      backgroundColor: config.bgColor,
                    }}
                  >
                    {log.level.toUpperCase()}
                  </span>
                  <span className="log-message">{log.message}</span>
                </div>
              )
            })}
          </div>
        )}
      </div>
    </Modal>
  )
}
